<template>
  <div class="app-container">
    <el-form
      v-show="showSearch"
      ref="queryForm"
      :model="queryParams"
      inline
    >
      <el-form-item label="菜单名称" prop="menuName">
        <el-input
          v-model="queryParams.menuName"
          placeholder="请输入菜单名称"
          clearable
          size="small"
          @keyup.enter="getList"
        ></el-input>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryParams.status"
          filterable
          placeholder="菜单状态"
          clearable
          size="small"
        >
          <el-option
            v-for="dict in dicts[DictDirection.是否禁用字典]"
            :key="dict.dictValue"
            :label="dict.dictLabel"
            :value="dict.dictValue"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          :icon="Search"
          size="small"
          @click="getList"
        >
          搜索
        </el-button>
        <el-button :icon="Refresh" size="small" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <button-tools v-model:showSearch="showSearch" @refresh="getList">
      <el-button
        type="primary"
        :icon="Plus"
        size="small"
        @click="handleAdd"
      >
        新增
      </el-button>
    </button-tools>

    <el-table
      v-loading="loading"
      :data="menuList"
      border
      row-key="menuId"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column
        prop="menuName"
        label="菜单名称"
        :show-overflow-tooltip="true"
        min-width="160"
      ></el-table-column>
      <el-table-column
        prop="icon"
        label="图标"
        align="center"
        width="100"
      >
        <template #default="{ row }">
          <svg-icon :name="row.icon"></svg-icon>
        </template>
      </el-table-column>
      <el-table-column
        prop="orderNum"
        label="排序"
        min-width="60"
        align="center"
      ></el-table-column>
      <el-table-column
        prop="perms"
        label="权限标识"
        show-overflow-tooltip
        align="center"
      ></el-table-column>
      <el-table-column
        prop="component"
        label="组件路径"
        show-overflow-tooltip
        align="center"
      ></el-table-column>
      <el-table-column
        prop="status"
        label="状态"
        min-width="80"
        :formatter="statusFormat"
        align="center"
      ></el-table-column>
      <el-table-column
        label="创建时间"
        align="center"
        show-overflow-tooltip
        prop="createTime"
      >
        <template #default="{ row }">
          <span>{{ row.createTime }}</span>
        </template>
      </el-table-column>
      <el-table-column
        label="操作"
        align="center"
        min-width="162"
        class-name="small-padding fixed-width custormFixedCol"
      >
        <template #default="{ row }">
          <el-button
            v-hasPermi="['system:menu:edit']"
            type="primary"
            text
            :icon="Edit"
            @click="handleUpdate(row)"
          >
            修改
          </el-button>
          <el-button
            v-hasPermi="['system:menu:add']"
            type="primary"
            text
            :icon="Plus"
            @click="handleAdd(row)"
          >
            新增
          </el-button>
          <el-button
            v-hasPermi="['system:menu:remove']"
            type="primary"
            text
            :icon="Delete"
            @click="handleDelete(row)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      v-model:model-value="open"
      :close-on-click-modal="false"
      :title="title"
      width="50%"
      append-to-body
    >
      <el-form
        ref="myForm"
        label-position="top"
        :model="form"
        :rules="rules"
        label-width="4rem"
      >
        <el-row justify="center">
          <el-col :span="24">
            <el-form-item label="上级菜单" prop="parentId">
              <!-- <treeselect v-model="form.parentId" :options="menuOptions" :normalizer="normalizer" :show-count="true" placeholder="选择上级菜单" /> -->
              <el-cascader
                ref="cascader"
                v-model="form.parentId"
                :options="menuOptions"
                :props="cascaderProps"
                clearable
                placeholder="选择上级菜单"
              />
            </el-form-item>
          </el-col>

          <el-col :span="24">
            <el-form-item label="菜单类型" prop="menuType">
              <el-radio-group v-model="form.menuType">
                <el-radio label="M">目录</el-radio>
                <el-radio label="C">菜单</el-radio>
                <el-radio label="F">按钮</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="菜单图标">
              <el-popover
                v-model="menuIconShow"
                placement="bottom-start"
                :width="500"
                trigger="click"
              >
                <IconSelect ref="iconSelect" @selected="selected" />
                <template #reference>
                  <el-input
                    ref="selectIcon"
                    v-model="form.icon"
                    placeholder="悬浮选择图标"
                    style="width: 240px; height: 30px;"
                    readonly
                  >
                    <template #prefix>
                      <svg-icon v-if="form.icon" :name="form.icon" style="height: 0.15rem; width: 0.2rem;" />
                      <el-icon v-else class="el-input__icon" style="height: 2rem; width: 0.2rem;">
                        <search />
                      </el-icon>
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="菜单名称" prop="menuName">
              <el-input v-model="form.menuName" style="width: 240px;" placeholder="请输入菜单名称"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="显示排序" prop="orderNum">
              <el-input-number v-model="form.orderNum" controls-position="right" :min="0"></el-input-number>
            </el-form-item>
          </el-col>
          <el-col v-if="form.menuType == 'C' || form.menuType == 'M'" :span="12">
            <el-form-item label="组件路径" prop="component">
              <el-input v-model="form.component" style="width: 240px;" placeholder="请输入组件路径"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'F'" label="路由地址" prop="path">
              <el-input v-model="form.path" style="width: 240px;" placeholder="请输入路由地址"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'F'" label="是否外链">
              <el-radio-group v-model="form.isFrame">
                <el-radio label="0">是</el-radio>
                <el-radio label="1">否</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'M'" label="权限标识">
              <el-input v-model="form.perms" placeholder="请输入权限标识"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'F'" label="显示状态">
              <el-radio-group v-model="form.visible">
                <el-radio v-for="dict in dicts[DictDirection.是否禁用字典]" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="form.menuType != 'F'" label="菜单状态">
              <el-radio-group v-model="form.status">
                <el-radio v-for="dict in dicts[DictDirection.系统显示隐藏]" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div>
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ElMessage, ElMessageBox, FormRules } from 'element-plus'
import { Refresh, Search, Plus, Delete, Edit } from '@element-plus/icons-vue'
import { reactive, ref, getCurrentInstance } from 'vue'
import { handleTree, depClone, selectDictLabel } from '@/utils/index'
import { listMenu, getMenu, addMenu, updateMenu, delMenu } from '@/api/system/menu'
import useDicts, { DictDirection } from '@/store/modules/dicts'

const dicts = useDicts()
dicts.setDicts(DictDirection.是否禁用字典)
dicts.setDicts(DictDirection.系统显示隐藏)

const loading = ref(false),
  showSearch = ref(true),
  queryForm = ref(null),
  myForm = ref(null),
  selectIcon = ref(null),
  cascaderProps = {
    checkStrictly: true,
    label: 'menuName',
    value: 'menuId',
    emitPath: false,
  },
  rules: FormRules = {
    menuName: [{ required: true, message: '菜单名称不能为空', trigger: 'blur' }],
    orderNum: [
      {
        required: true,
        type: 'number',
        message: '菜单顺序不能为空',
        trigger: 'blur',
      },
    ],
    path: [{ required: true, message: '路由地址不能为空', trigger: 'blur' }],
  },
  {
    appContext: {
      config: {
        globalProperties: { $resetForm, $validateForm },
      },
    },
  } = getCurrentInstance(),
  title = ref(''),
  open = ref(false),
  formOrigin = {
    parentId: 0,
    menuType: 'M',
    icon: 'circular',
    menuName: undefined,
    orderNum: 0,
    component: undefined,
    perms: undefined,
    path: undefined,
    menuId: undefined,
    isFrame: '1',
    visible: 0,
    status: 0,
  }
const menuOptions = ref([]),
  menuIconShow = ref(false),
  menuList = ref([]),
  queryParams = reactive({ menuName: undefined, visible: undefined, status: undefined }),
  form = ref(formOrigin)
const getList = async () => {
  loading.value = true
  const res = await listMenu(queryParams)
  try {
    if (res.code === 200) {
      menuList.value = handleTree(res.data, 'menuId')
    } else {
      ElMessage.error(res.msg)
    }
  } catch (err) {
    console.log(err)
    ElMessage.error(err)
  } finally {
    loading.value = false
  }
}
getList()
const resetQuery = () => {
  $resetForm(queryForm.value)
}
const submitForm = () => {
  $validateForm(myForm.value, () => {
    if (form.value.menuId != undefined) {
      updateMenu(form.value).then((res) => {
        if (res.code == 200) {
          ElMessage.success('修改成功')
          open.value = false
          getList()
        }
      })
    } else {
      addMenu(form.value).then((res) => {
        if (res.code == 200) {
          ElMessage.success('新增成功')
          open.value = false
          getList()
        }
      })
    }
  })
}
const cancel = () => {
  resetQuery()
  open.value = false
}
const handleAdd = (row: { menuId?: number } | MouseEvent) => {
  reset()
  getTreeselect()
  if ('menuId' in row) {
    form.value.parentId = row.menuId
  } else {
    form.value.parentId = 0
  }
  title.value = '添加菜单'
  open.value = true
}
const getTreeselect = () => {
  listMenu().then((res) => {
    menuOptions.value = []
    const menu = { menuId: 0, menuName: '主类目', expandTrigger: 'click', children: [] }
    menu.children = handleTree(res.data, 'menuId')
    menuOptions.value.push(menu)
  })
}
const reset = () => {
  form.value = depClone(formOrigin)
  $resetForm(myForm.value)
}
const selected = (data: string) => {
  form.value.icon = data
  selectIcon.value.$el.click()
}
const handleUpdate = (row) => {
  reset()
  getTreeselect()
  getMenu(row.menuId).then((res) => {
    res.data.visible = Number(res.data.visible)
    form.value = res.data
    open.value = true
    title.value = '修改菜单'
  })
}
const handleDelete = (row) => {
  ElMessageBox.confirm(`是否确认删除名称为"${ row.menuName }"的数据项?`, '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
  .then(() => delMenu(row.menuId))
  .then(() => {
    getList()
    ElMessage.success('删除成功')
  })
  .catch((err) => console.log(err))
}
const statusFormat = (row) => selectDictLabel(dicts[DictDirection.系统显示隐藏], row.status)
</script>
